﻿using System;
using System.Text;
using System.Data;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SERP.Controllers{
    public class Controller
    {
		static Controller()
		{
			InitCache();
		}		
		public static void AddIndexToTable(DataTable tblData){
			if(tblData==null)return;
			if(tblData.Columns.Contains("STT")){
				ResetTableIndex(tblData);
			}
			else{
				tblData.Columns.Add("STT",typeof(int));
				ResetTableIndex(tblData);
			}
		}
		public static void ResetTableIndex(DataTable tblData){
			if(!tblData.Columns.Contains("STT"))return;
			for(int i=0;i<tblData.Rows.Count;i++){
				tblData.Rows[i]["STT"] = i + 1;
			}
		}
		public static decimal ConvertNumber(object oNumber){
			decimal n=0;			
			if(oNumber!=null)decimal.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public static int ConvertInt(object oNumber){
			int n=0;
			if(oNumber!=null)int.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public static double ConvertDouble(object oNumber){
			double n=0;
			if(oNumber!=null)double.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public static double ConvertSingle(object oNumber){
			Single n=0;
			if(oNumber!=null)float.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public static long ConvertLong(object oNumber){
			Int64 n=0;
			if(oNumber!=null)Int64.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public  static byte ConvertByte(object oNumber){
			byte n=0;
			byte.TryParse(oNumber.ToString(),out n);
			return n;
		}
		public static bool ConvertBool(object oBool){
			if(oBool==null)return false;
			bool result=false;
			try{
				result=Convert.ToBoolean(oBool);
			}
			catch{
			}
			return result;
		}
		public static DateTime ConvertDateTime(object oDate){
		    if(oDate==null)return DateTime.Now;
			DateTime result=DateTime.Now;
			try{
				result=Convert.ToDateTime(oDate);
			}
			catch{
			}
			return result;
		}
		public static void AddCache(string key,object data){
			if (Cache == null)
			{
				InitCache();
			}
			Cache.Set(key,data,CacheTimeOut);
		}
		protected static int CacheTimeOut=-1;
		private static ICacheManager _Cache;
		public static ICacheManager Cache{
			get{
			    return _Cache;
			}
		}
		public static void InitCache(){
			_Cache = new CacheManager();
		}
    }
    /// <summary>
    /// Represents a StaticCache
    /// </summary>
    public class CacheManager : ICacheManager
    {
        private Dictionary<string,object> _context;
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="context">Context</param>
        public CacheManager()
        {
            this._context = new Dictionary<string,object>();            
        }       
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        public T Get<T>(string key)
        {
            if (!this._context.ContainsKey(key))
                return default(T);
            return (T)_context[key];
        }
        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        public void Set(string key, object data, int cacheTime)
        {
             if (this._context.ContainsKey(key))
			 {
				this._context[key]=data;
			 }
             else{
				this._context.Add(key, data);
             }
        }
        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        public bool IsSet(string key)
        {
            if (_context == null)
                return false;
            return (_context[key] != null);
        }
        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        public void Remove(string key)
        {
			if (_context == null)
                return;
            _context.Remove(key);
        }
        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        public void RemoveByPattern(string pattern)
        {
            if (_context == null)
                return;
            var enumerator = _context.GetEnumerator();
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var keysToRemove = new List<String>();
            while (enumerator.MoveNext())
            {
                if (regex.IsMatch(enumerator.Current.Key.ToString()))
                {
                    keysToRemove.Add(enumerator.Current.Key.ToString());
                }
            }
            foreach (string key in keysToRemove)
            {
                _context.Remove(key);
            }
        }
        /// <summary>
        /// Clear all cache data
        /// </summary>
        public void Clear()
        {
            if (_context == null)
                return;
            var enumerator = _context.GetEnumerator();
            var keysToRemove = new List<String>();
            while (enumerator.MoveNext())
            {
                keysToRemove.Add(enumerator.Current.Key.ToString());
            }
            foreach (string key in keysToRemove)
            {
                _context.Remove(key);
            }
        }
    }
    public interface ICacheManager{
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        T Get<T>(string key);
        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        void Set(string key, object data, int cacheTime);
        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        bool IsSet(string key);
        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        void Remove(string key);
        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        void RemoveByPattern(string pattern);
        /// <summary>
        /// Clear all cache data
        /// </summary>
        void Clear();
    }
}
